package com.venutech.gongan.service.impl;

import com.baomidou.mybatisplus.plugins.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.project.system.mapper.SysUserMapper;
import com.venutech.gongan.dao.DevicePermissionHistoryMapper;
import com.venutech.gongan.dao.QdsxjMapper;
import com.venutech.gongan.entity.DevicePermissionHistory;
import com.venutech.gongan.enums.DevicePermissionStatus;
import com.venutech.gongan.service.DevicePermissionService;
import com.venutech.gongan.vo.DevicePermissionVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import com.venutech.gongan.dao.DevicePermissionMapper;
import com.venutech.gongan.entity.DevicePermission;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.*;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;

@Service
@Slf4j
public class DevicePermissionServiceImpl implements DevicePermissionService {

    @Resource
    private DevicePermissionMapper devicePermissionMapper;

    @Resource
    private DevicePermissionHistoryMapper devicePermissionHistoryMapper;

    @Resource
    private QdsxjMapper qdsxjMapper;

    @Resource
    private SysUserMapper sysUserMapper;

    
    public int insert(DevicePermission record) {
        return devicePermissionMapper.insert(record);
    }

    
    public int insertSelective(DevicePermission record) {
        return devicePermissionMapper.insertSelective(record);
    }


    @Override
    public int addDevicePermission(int deviceId, int userId, int createBy) {
        boolean exist = devicePermissionMapper.selectByDeviceId(deviceId)
                .stream().anyMatch(devicePermission -> devicePermission.getUserId().equals(userId));

        if (exist) {
            return 0;
        }

        log.info(String.format("创建设备权限，设备ID: %d, 用户id: %d, 创建者id: %d", deviceId, userId, createBy));
        return insert(new DevicePermission(deviceId, userId, createBy, new Date(), DevicePermissionStatus.ENABLE.getStatus()));
    }

    @Override
    @Transactional
    public void removeDevicePermission(int deviceId, int userId, int operatorId) {
        DevicePermission devicePermission = devicePermissionMapper.selectByDeviceIdAndUserId(deviceId, userId);

        if(Objects.isNull(devicePermission)) {
            // 没有权限, 新建权限
            devicePermission = new DevicePermission(deviceId, userId, userId, new Date(), DevicePermissionStatus.DISABLE.getStatus());
            devicePermissionMapper.insert(devicePermission);
            DevicePermissionHistory history = DevicePermissionHistory.builder()
                    .deviceId(deviceId)
                    .userId(userId)
                    .operate(DevicePermissionStatus.DISABLE.getStatus())
                    .operatorId(operatorId)
                    .operateTime(new Date())
                    .build();
            devicePermissionHistoryMapper.insert(history);
        } else {
            // 已有, 但是不是已有权限或者申请状态中
            if(isEnableOrApplying(devicePermission)) {
                devicePermissionMapper.updateStatus(deviceId, userId, DevicePermissionStatus.DISABLE);
                DevicePermissionHistory history = DevicePermissionHistory.builder()
                        .deviceId(deviceId)
                        .userId(userId)
                        .operate(DevicePermissionStatus.DISABLE.getStatus())
                        .operatorId(operatorId)
                        .operateTime(new Date())
                        .build();
                devicePermissionHistoryMapper.insert(history);
            }
        }


        log.info(String.format("禁用设备权限:设备id: %d, 用户id: %d, 操作者: %d", deviceId, userId, operatorId));
    }


    @Override
    public void enableDevicePermissionApply(int deviceId, int userId, int operatorId) {
        DevicePermission devicePermission = devicePermissionMapper.selectByDeviceIdAndUserId(deviceId, userId);

        if(Objects.isNull(devicePermission)) {
            throw new ServiceException("用户尚未申请!");
        } else {
            // 已有, 但是不是已有权限或者申请状态中
            if(isApplying(devicePermission)) {
                devicePermissionMapper.updateStatus(deviceId, userId, DevicePermissionStatus.ENABLE);
                DevicePermissionHistory history = DevicePermissionHistory.builder()
                        .deviceId(deviceId)
                        .userId(userId)
                        .operate(DevicePermissionStatus.ENABLE.getStatus())
                        .operatorId(operatorId)
                        .operateTime(new Date())
                        .build();
                devicePermissionHistoryMapper.insert(history);
            }
        }


        log.info(String.format("禁用设备权限:设备id: %d, 用户id: %d, 操作者: %d", deviceId, userId, operatorId));
    }

    @Override
    public List<DevicePermission> findByDeviceId(int deviceId) {
        return devicePermissionMapper.selectByDeviceId(deviceId);
    }

    @Override
    public void updateDevicePermission(int deviceId, List<Integer> userIds, int createBy) {
        // 全部删除
        devicePermissionMapper.deleteByDeviceId(deviceId);
        // 批量增加
        userIds.stream().map(id -> new DevicePermission(deviceId, id, createBy, new Date(), DevicePermissionStatus.ENABLE.getStatus())).forEach(devicePermissionMapper::insert);
    }

    @Override
    @Transactional
    public void requestDevicePermission(int userId, int deviceId) {
        DevicePermission devicePermission = devicePermissionMapper.selectByDeviceIdAndUserId(deviceId, userId);

        if(Objects.isNull(devicePermission)) {
            // 没有权限, 新建权限
            devicePermission = new DevicePermission(deviceId, userId, userId, new Date(), DevicePermissionStatus.APPLYING.getStatus());
            devicePermissionMapper.insert(devicePermission);
            DevicePermissionHistory history = DevicePermissionHistory.builder()
                    .deviceId(deviceId)
                    .userId(userId)
                    .operate(DevicePermissionStatus.APPLYING.getStatus())
                    .operatorId(userId)
                    .operateTime(new Date())
                    .build();
            devicePermissionHistoryMapper.insert(history);
            log.info(String.format("申请设备权限: %d 申请 %d", userId, deviceId));
        } else {
            // 已有, 但是不是已有权限或者申请状态中
            if(!isEnableOrApplying(devicePermission)) {
               devicePermissionMapper.updateStatus(deviceId, userId, DevicePermissionStatus.APPLYING);
                DevicePermissionHistory history = DevicePermissionHistory.builder()
                        .deviceId(deviceId)
                        .userId(userId)
                        .operate(DevicePermissionStatus.APPLYING.getStatus())
                        .operatorId(userId)
                        .operateTime(new Date())
                        .build();
                devicePermissionHistoryMapper.insert(history);
                log.info(String.format("申请设备权限: %d 申请 %d", userId, deviceId));
            }
        }
    }

    @Override
    public List<DevicePermissionHistory> findHistory(int deviceId, int userId) {
        return devicePermissionHistoryMapper.selectByDeviceIdAndUserId(deviceId, userId);
    }

    @Override
    public Page<DevicePermissionVO> findAll(int page, int size) {
        PageHelper.startPage(page, size);
        Page<DevicePermissionVO> record = new Page<>(page, size);
        List<DevicePermission> devicePermissions = devicePermissionMapper.selectAll();

        record.setTotal(new PageInfo<>(devicePermissions).getTotal());

        List<DevicePermissionVO> vos = devicePermissions.stream().map(devicePermission -> {
            DevicePermissionVO vo = new DevicePermissionVO();
            vo.setDevicePermission(devicePermission);
            vo.setQdsxj(qdsxjMapper.getById(devicePermission.getDeviceId()));
            vo.setUser(sysUserMapper.selectUserById(devicePermission.getUserId().longValue()));
            return vo;
        }).collect(Collectors.toList());

        record.setRecords(vos);
        return record;
    }

    private boolean isEnableOrApplying(DevicePermission devicePermission) {
        return DevicePermissionStatus.ENABLE.getStatus().equals(devicePermission.getStatus()) ||
                isApplying(devicePermission);
    }

    private boolean isApplying(DevicePermission devicePermission) {
        return DevicePermissionStatus.APPLYING.getStatus().equals(devicePermission.getStatus());
    }
}
